package org.sws.domain.strategy.service.raffle;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.sws.domain.strategy.model.entity.StrategyAwardEntity;
import org.sws.domain.strategy.model.valobj.*;
import org.sws.domain.strategy.repository.IStrategyRepository;
import org.sws.domain.strategy.service.AbstractRaffleStrategy;
import org.sws.domain.strategy.service.IRaffleAward;
import org.sws.domain.strategy.service.IRaffleRule;
import org.sws.domain.strategy.service.IRaffleStock;
import org.sws.domain.strategy.service.armory.IStrategyDispatch;
import org.sws.domain.strategy.service.rule.chain.ILogicChain;
import org.sws.domain.strategy.service.rule.chain.factory.LogicChainFactory;
import org.sws.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import org.sws.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;

import java.util.*;

/**
 * @Author sws
 * @Date 2025/2/18 15:55
 * @description: 默认的抽奖策略实现
 */
@Slf4j
@Service
public class DefaultRaffleStrategy extends AbstractRaffleStrategy implements IRaffleStock, IRaffleAward, IRaffleRule {


    protected DefaultRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch, LogicChainFactory logicChainFactory, DefaultTreeFactory defaultTreeFactory) {
        super(repository, strategyDispatch, logicChainFactory, defaultTreeFactory);
    }

    @Override
    public ChainStrategyAwardVO raffleLogicChain(String userId, Long strategyId) {
        // 构造抽奖策略规则过滤责任链
        ILogicChain logicChain = logicChainFactory.createLogicChain(strategyId);
        // 策略规则过滤责任链，过滤后进行查询装配好的策略奖品map获得随机奖品id
        return logicChain.logic(userId, strategyId);
    }

    @Override
    public DefaultTreeFactory.StrategyAwardData raffleLogicTree(String userId, Long strategyId, Integer awardId, Date activityEndTime) {
        StrategyAwardRuleModelVO strategyAwardRuleModelVO = repository.queryStrategyAwardRuleModelVO(strategyId, awardId);
        if(Objects.isNull(strategyAwardRuleModelVO)){
            // 该奖品没有抽奖规则，直接返回
            return DefaultTreeFactory.StrategyAwardData.builder().awardId(awardId).build();
        }
        RuleTreeVO ruleTreeVO = repository.queryRuleTreeVOByTreeId(strategyAwardRuleModelVO.getRuleModels());
        if (null == ruleTreeVO) {
            throw new RuntimeException("存在抽奖策略配置的规则模型 Key，未在库表 rule_tree、rule_tree_node、rule_tree_line 配置对应的规则树信息 " + strategyAwardRuleModelVO.getRuleModels());
        }
        IDecisionTreeEngine treeEngine = defaultTreeFactory.openLogicTree(ruleTreeVO);
        return treeEngine.process(userId, strategyId, awardId, activityEndTime);
    }

    @Override
    public void updateStrategyAwardStock(Long strategyId, Integer awardId) {
        repository.updateStrategyAwardStock(strategyId, awardId);
    }

    @Override
    public StrategyAwardStockKeyVO takeQueueValue(Long strategyId, Integer awardId) {
        return repository.takeQueueValue(strategyId, awardId);
    }

    @Override
    public List<StrategyAwardEntity> queryRaffleStrategyAwardList(Long strategyId) {
        return repository.queryStrategyAwardList(strategyId);
    }

    @Override
    public List<StrategyAwardEntity> queryRaffleStrategyAwardListByActivityId(Long activityId) {
        return repository.queryStrategyAwardListByActivityId(activityId);
    }

    @Override
    public List<StrategyAwardStockKeyVO> queryOpenActivityStrategyAwardList() {
        return repository.queryOpenActivityStrategyAwardList();
    }

    @Override
    public Map<String, Integer> queryAwardRuleLockCount(String[] treeIds) {
        return repository.queryAwardRuleLockCount(treeIds);
    }

    @Override
    public List<RuleWeightVO> queryAwardRuleWeightByActivityId(Long activityId) {
        Long strategyId = repository.queryRaffleActivityByActivityId(activityId);
        return repository.queryAwardRuleWeight(strategyId);
    }
}
